package flexconsole.view {
	import flexconsole.AppFacade;
	import flexconsole.ConfigKeys;
	import flexconsole.model.ICategoryProxy;
	import flexconsole.model.IConfigProxy;
	import flexconsole.model.ILogMessageProxy;
	import flexconsole.model.LogLevelModel;
	import flexconsole.view.component.Grid;
	
	import flexunit.framework.Assert;
	
	import mx.collections.ListCollectionView;
	import mx.controls.dataGridClasses.DataGridColumn;
	import mx.events.DataGridEvent;
	import mx.logging.ILogger;
	import mx.logging.Log;
	
	import org.puremvc.as3.interfaces.INotification;
	import org.puremvc.as3.patterns.mediator.Mediator;
	
	/**
	 * Mediator for the Grid view, which displays the log messages.
	 *
	 * @author ivanchoo
	 *
	 */
	public class GridMediator extends Mediator {
		
		static private var logger:ILogger = Log.getLogger("flexconsole.view.GridMediator");
		
		protected var dataProvider:ListCollectionView;
		
		protected var logLevelModel:LogLevelModel;
		
		protected var keyword:String;
		
		private var isViewDirty:Boolean = false;
		
		private var isDataDirty:Boolean = false;
		
		public function GridMediator(mediatorName:String = null, viewComponent:Object = null) {
			super(mediatorName, viewComponent);
		}
		
		public function get view():Grid {
			return viewComponent as Grid;
		}
		
		public function get appFacade():AppFacade {
			return facade as AppFacade;
		}
		
		override public function onRegister():void {
			logger.debug("onRegister()");
			super.onRegister();
			Assert.assertNotNull(appFacade);
			Assert.assertNotNull(view);
			dataProvider = new ListCollectionView();
			dataProvider.list = appFacade.logMessageProxy.collection;
			dataProvider.filterFunction = collectionFilterFunction;
			view.resourceBundle = appFacade.resourceBundle;
			view.dataProvider = dataProvider;
			view.datagrid.addEventListener(DataGridEvent.COLUMN_STRETCH, onDataGridEvent);
			updateData();
			updateView();
		}
		
		override public function listNotificationInterests():Array {
			return [ AppFacade.DATA_CHANGE ];
		}
		
		override public function handleNotification(notification:INotification):void {
			if (AppFacade.PROXYNAME_CONFIG == notification.getType()) {
				if (notification.getBody() == null) {
					// full refresh
					invalidateData();
				} else {
					//  config has changed, we watch the following key changes
					switch (notification.getBody()) {
						case ConfigKeys.FILTER_LOG_LEVELS:
						case ConfigKeys.FILTER_KEYWORD:
							invalidateData();
							break;
						case ConfigKeys.DATAGRID_COLUMN_WIDTHS:
						case ConfigKeys.SCROLL_LOCK:
							invalidateView();
					}
				}
			} else if (AppFacade.PROXYNAME_CATEGORY == notification.getType()) {
				//  category changed, we need to refresh all
				invalidateData();
			}
			//   note that we don't need to watch for logProxy changes
			//   as the collection bindngs take care of refreshes.
		}
		
		protected function invalidateData():void {
			if (view && !isDataDirty) {
				isDataDirty = true;
				view.callLater(updateData);
			}
		}
		
		protected function invalidateView():void {
			if (view && !isViewDirty) {
				isViewDirty = true;
				view.callLater(updateView);
			}
		}
		
		protected function updateData():void {
			logger.debug("updateData()");
			var configProxy:IConfigProxy = appFacade.configProxy;
			isDataDirty = false;
			logLevelModel = new LogLevelModel(configProxy.getValue(ConfigKeys.FILTER_LOG_LEVELS));
			keyword = configProxy.getValue(ConfigKeys.FILTER_KEYWORD, null);
			
			if (keyword) {
				keyword = keyword.toLowerCase();
			}
			dataProvider.refresh();
			updateView();
		}
		
		protected function updateView():void {
			logger.debug("updateView()");
			isViewDirty = false;
			var configProxy:IConfigProxy = appFacade.configProxy;
			var widthStr:String = configProxy.getValue(ConfigKeys.DATAGRID_COLUMN_WIDTHS, null) as String;
			
			if (widthStr && widthStr.length) {
				var widths:Array = widthStr.split(",");
				var i:int = widths.length;
				var col:DataGridColumn;
				var value:Number;
				
				while (i--) {
					col = view.datagrid.columns[i] as DataGridColumn;
					value = Number(widths[i]);
					
					if (col.width != value) {
						col.width = value;
					}
				}
			}
			view.scrollLock = configProxy.getValue(ConfigKeys.SCROLL_LOCK, true);
		}
		
		protected function collectionFilterFunction(item:XML):Boolean {
			var logProxy:ILogMessageProxy = appFacade.logMessageProxy;
			
			if (!logLevelModel.isEnabled(logProxy.level(item))) {
				return false;
			}
			var categoryProxy:ICategoryProxy = appFacade.categoryProxy;
			var category:XML = categoryProxy.find(logProxy.category(item));
			
			if (!(category is XML && categoryProxy.isSelected(category))) {
				return false;
			}
			
			if (keyword && logProxy.message(item).toLowerCase().indexOf(keyword) < 0) {
				return false;
			}
			return true;
		}
		
		protected function onDataGridEvent(event:DataGridEvent):void {
			var configProxy:IConfigProxy = appFacade.configProxy;
			var columns:Array = view.datagrid.columns;
			var widths:Array = new Array();
			var i:int = columns.length;
			var col:DataGridColumn;
			
			while (i--) {
				col = columns[i] as DataGridColumn;
				widths.unshift(col.width);
			}
			widths.pop();
			configProxy.setValue(ConfigKeys.DATAGRID_COLUMN_WIDTHS, widths.join(","));
		}
	
	}
}

